package com.wondertek.service.service.business.impl;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wondertek.common.base.Result;
import com.wondertek.common.util.base.DateUtil;
import com.wondertek.common.util.base.IpUtils;
import com.wondertek.service.entity.business.AlarmDeviceMessagePo;
import com.wondertek.service.entity.business.SdkErrorRecordPo;
import com.wondertek.service.mapper.business.AlarmDeviceMessageMapper;
import com.wondertek.service.mapper.business.SdkErrorRecordMapper;
import com.wondertek.service.sdk.iotdh.constant.MsgType;
import com.wondertek.service.sdk.iotdh.dto.req.CallBackReq;
import com.wondertek.service.sdk.iotdh.dto.res.AlarmDeviceMessage;
import com.wondertek.service.sdk.iotdh.dto.res.InfoRes;
import com.wondertek.service.sdk.iotdh.dto.res.PushDhMessage;
import com.wondertek.service.service.business.AlarmDeviceService;

import com.wondertek.service.service.business.DeviceErrorRecordService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.CompletableFuture;


@Service
@Slf4j
public class AlarmDeviceServiceImpl extends ServiceImpl<AlarmDeviceMessageMapper, AlarmDeviceMessagePo> implements AlarmDeviceService {

    @Resource
    private DeviceErrorRecordService deviceErrorRecordService;

    @Resource
    private SdkErrorRecordMapper sdkErrorRecordMapper;

    @Override
    public Result<?> receiveMessages(Object object) {

        log.info("接收时间->{},==>{}", DateUtil.date2LongString(new Date()), "=====================回调消息中=======================");
        try {
            CallBackReq message = JSONObject.parseObject(JSONObject.toJSONString(object), CallBackReq.class);

            Integer type = message.getType();//推送类型 1告警 2设备上下线 3 设备增删
            Object data = message.getData();

            AlarmDeviceMessage deviceMessage = JSONObject.parseObject(data.toString(), AlarmDeviceMessage.class);
            deviceMessage.setType(type);
            AlarmDeviceMessagePo po = new AlarmDeviceMessagePo();
            BeanUtil.copyProperties(deviceMessage, po);
            this.save(po);//保存推数数据
            try {
                CompletableFuture.runAsync(() -> {//异步处理
                    executeAlarmMessage(deviceMessage);
                }).join();
            } catch (Exception e) {
                log.info("异步错误时间->{},错误提示->{}", DateUtil.date2LongString(new Date()), e.getMessage());
            }
        } catch (Exception e) {
            log.info("接收时间->{},错误提示->{}", DateUtil.date2LongString(new Date()), e.getMessage());
            //回调失败 记录一下
            SdkErrorRecordPo errorRecordPo = new SdkErrorRecordPo();
            errorRecordPo.setErrorInfo(e.getMessage());
            errorRecordPo.setIpAddress(IpUtils.getIpAddr());
            errorRecordPo.setInputParameters(object.toString());
            errorRecordPo.setSdkAddress("receiveMessages");
            try {
                sdkErrorRecordMapper.insert(errorRecordPo);
            } catch (Exception ex) {
            }
        }
        log.info("接收成功时间->{},==>{}", DateUtil.date2LongString(new Date()), "=====================回调消息成功=======================");
        return Result.success();
    }

    public void executeAlarmMessage(AlarmDeviceMessage po) {
        //需要传的参数:类别  设备sn  消息typle 告警时间
        //AlarmDeviceMessage 消息
        //根据type区分 推送类型 1告警 2设备上下线 3 设备增删
        InfoRes info = JSONObject.parseObject(po.getInfo(), InfoRes.class);//info信息
        PushDhMessage dhMessage = new PushDhMessage();
        log.info("打印data信息->{}", JSONObject.toJSONString(po));
        log.info("打印info信息->{}", JSONObject.toJSONString(info));

        if (1 == po.getType()) {//告警
            if (info != null)
                dhMessage.setDeviceSn(StringUtils.isNotEmpty(info.getAccessoryId()) ? info.getAccessoryId() : po.getDeviceSn());//设备sn码
            if (info != null)
                dhMessage.setMsgType(StringUtils.isNotEmpty(info.getAlarmType()) ? info.getAlarmType() : info.getMsgType());//报警类型
            dhMessage.setStatus(po.getAlarmStatus());//消警状态 0 未消警 1 已消警
            if (info != null)
                dhMessage.setAlarmTime(info.getUtcTime() != null ? info.getUtcTime() : System.currentTimeMillis());//报警时间
        } else if (2 == po.getType()) {//上线、下线
            //设备上线、下线只有deviceId、deviceSn、orgId、status
            if (0 == po.getStatus()) {//2-未激活，1-在线，0-离线
                dhMessage.setMsgType("offline");//报警类型
            } else {
                dhMessage.setMsgType("online");//报警类型
            }
            dhMessage.setDeviceSn(po.getDeviceSn());//设备sn码
            dhMessage.setStatus(po.getStatus());//2-未激活，1-在线，0-离线
            dhMessage.setAlarmTime(System.currentTimeMillis());//报警时间==系统时间
        } else if (3 == po.getType()) {//新增、删除设备
            // 若是删除推送，只有 deviceId，deviceSn ，deviceOperate 三个属性
            if (0 == po.getDeviceOperate()) {
                dhMessage.setMsgType("add");//报警类型
            } else {
                dhMessage.setMsgType("delete");//报警类型
            }
            dhMessage.setDeviceSn(po.getDeviceSn());//设备sn码
            dhMessage.setStatus(po.getDeviceOperate());//设备操作⾏为 0删除 1新增
            dhMessage.setAlarmTime(System.currentTimeMillis());//报警时间=系统时间
        }
        //分为四大类 1、alarm  2、error 3、events  4、note 99、其它
        dhMessage.setType(MsgType.valueOfName(dhMessage.getMsgType()));
        log.info("PushDhMessage时间->{},PushDhMessage实体数据->{}", DateUtil.date2LongString(new Date()), dhMessage);
        log.info("executeAlarmMessage 调用 rollBackErrorRecord 方法");
        deviceErrorRecordService.rollBackErrorRecord(dhMessage);
    }
}

